package ces.lawsuit.util;

import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import com.jfinal.core.Controller;

public class ClassSearcher {
	 
    
	 
    private static List<File> classFiles;
 
 
 
    /**
 
     * 递归查找文件
 
     * 
 
     * @param baseDirName
 
     *            查找的文件夹路径
 
     * @param targetFileName
 
     *            需要查找的文件名
 
     */
 
    private  static List<File> findFiles(String baseDirName, String targetFileName) {
 
 
        /**
 
         * 算法简述： 从某个给定的需查找的文件夹出发，搜索该文件夹的所有子文件夹及文件，
 
         * 若为文件，则进行匹配，匹配成功则加入结果集，若为子文件夹，则进队列。 队列不空，重复上述操作，队列为空，程序结束，返回结果。
 
         */
 
        classFiles = new ArrayList<File>();
 
        String tempName = null;
 
        // 判断目录是否存在
 
        File baseDir = new File(baseDirName);
 
        if (!baseDir.exists() || !baseDir.isDirectory()) {
 
            System.out.println("文件查找失败：" + baseDirName + "不是一个目录！");
 
        } else {
 
            String[] filelist = baseDir.list();
 
            for (int i = 0; i < filelist.length; i++) {
 
                File readfile = new File(baseDirName + File.separator
 
                        + filelist[i]);
 
                if (!readfile.isDirectory()) {
 
                    tempName = readfile.getName();
 
                    if (ClassSearcher.wildcardMatch(targetFileName, tempName)) {
 
                        classFiles.add(readfile.getAbsoluteFile());
 
                    }
 
                } else if (readfile.isDirectory()) {
 
                    classFiles.addAll(findFiles(baseDirName + File.separator
 
                            + filelist[i], targetFileName));
 
                }
 
            }
 
        }
 
        return classFiles;
 
    }
 
   public static List<Class<?>> getClasses(Class<?> clazz){
	   String classDir=ClassSearcher.class.getClassLoader().getResource("/").getPath();
	   File classDirFile=new File(classDir);
	   List<Class<?>> classList=new ArrayList<Class<?>>();
	   scanFile(classDirFile,classList,clazz);
			   
	   
	   return classList;
	
}

private static void scanFile(File classDirFile,List<Class<?>> fileList,Class<?> clazz) {
	if(classDirFile.isDirectory()){
		   for(File f:classDirFile.listFiles()){
			   scanFile(f,fileList,clazz);
		   }
	   }else{
		   if(classDirFile.getName().indexOf(".class")>-1){
			   String className = className(classDirFile, "/classes");
			 //  String className=classDirFile.toString().substring(0, classDirFile.toString().length()-6);
			   try {
			 Class<?>  cl=	Class.forName(className);
			 if(null!=cl.getSuperclass()&&null!=cl.getSuperclass().getSimpleName()&&cl.getSuperclass().getSimpleName().equals(clazz.getSimpleName())){
				 fileList.add(cl);
			 }
			} catch (ClassNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			  // fileList.add(className);
			 //  System.out.println(className);
		   }
	   }
}
 
 
    @SuppressWarnings("unused")
	public static List<Class<?>> findClasses(Class<?> clazz) {
    	
 
        List<Class<?>> classList = new ArrayList<>();
        String classDir=ClassSearcher.class.getClassLoader().getResource("/").getPath();
        URL classPathUrl = ClassSearcher.class .getResource("/");
    //  System.out.println(ClassSearcher.class.getClassLoader().getResource("/").getPath() );
        List<File> classFileList = findFiles(classDir, "*.class");
        
		@SuppressWarnings("rawtypes")
		List <Class<?>> classesList=getClasses(clazz);
         
 
        String lib = new File(classPathUrl.getFile()).getParent() + "/lib/";
 
 
 
        for (File classFile : classFileList) {
 
            String className = className(classFile, "/classes");
 
            try {
 
                Class<?> classInFile = Class.forName(className);
 
                if (classInFile.getSuperclass() == clazz) {
 
                    classList.add(classInFile);
 
                }
 
            } catch (ClassNotFoundException e) {
 
                e.printStackTrace();
 
            }
 
        }
        classList.addAll(classesList);
        return classList;
 
    }
 
 
 
    private static String className(File classFile, String pre) {
 
        String objStr = classFile.toString().replaceAll("\\\\", "/");
 
        String className;
 
        className = objStr.substring(objStr.indexOf(pre) + pre.length(),
 
                objStr.indexOf(".class"));
 
        if (className.startsWith("/")) {
 
            className = className.substring(className.indexOf("/") + 1);
 
        }
 
        return className.replaceAll("/", ".");
 
    }
 
 
 
    /**
 
     * 通配符匹配
 
     * 
 
     * @param pattern
 
     *            通配符模式
 
     * @param str
 
     *            待匹配的字符串
 
     * <a href="http://my.oschina.net/u/556800" target="_blank" rel="nofollow">@return</a>  匹配成功则返回true，否则返回false
 
     */
 
    private static boolean wildcardMatch(String pattern, String str) {
 
        int patternLength = pattern.length();
 
        int strLength = str.length();
 
        int strIndex = 0;
 
        char ch;
 
        for (int patternIndex = 0; patternIndex < patternLength; patternIndex++) {
 
            ch = pattern.charAt(patternIndex);
 
            if (ch == '*') {
 
                // 通配符星号*表示可以匹配任意多个字符
 
                while (strIndex < strLength) {
 
                    if (wildcardMatch(pattern.substring(patternIndex + 1),
 
                            str.substring(strIndex))) {
 
                        return true;
 
                    }
 
                    strIndex++;
 
                }
 
            } else if (ch == '?') {
 
                // 通配符问号?表示匹配任意一个字符
 
                strIndex++;
 
                if (strIndex > strLength) {
 
                    // 表示str中已经没有字符匹配?了。
 
                    return false;
 
                }
 
            } else {
 
                if ((strIndex >= strLength) || (ch != str.charAt(strIndex))) {
 
                    return false;
 
                }
 
                strIndex++;
 
            }
 
        }
 
        return (strIndex == strLength);
 
    }
 
}